import numpy as np
import pandas as pd

# 参数设置
from matplotlib import pyplot as plt

v = -0.1
alpha = 0.2
tau = 17  # 时延
delta = 6  # 输入的步长延迟
h = 0.1  # 时间步长

# 时间向量
t_max = 601 + 6  # 考虑到 u(n + 6)
t = np.arange(-tau, t_max + h, h)
N = len(t)

# 初始化 u(t)
u = np.zeros(N)
u[t <= 0] = 1.2  # 当 t ≤ 0 时的初始条件

# 索引计算
tau_steps = int(tau / h)

# 找到 t 最接近 0 的索引
i0 = np.argmin(np.abs(t))

# 微分方程的函数定义
def f(u_n, u_tau):
    return v * u_n + alpha * u_tau / (1 + u_tau ** 10)

# 使用二阶 Runge-Kutta 方法进行积分
for i in range(i0, N - 1):
    u_n = u[i]
    u_tau = u[i - tau_steps]
    k1 = f(u_n, u_tau)
    k2 = f(u_n + h / 2, u_tau + k1 * (h / 2))  # 在中点处近似 u_tau 为 u_tau
    u[i + 1] = u_n + k2 * h

# 提取整数时间点的 u(n)
n_max = t_max  # 包含 u(n + 6)
n_values = np.arange(1, n_max + 1)
u_n = np.zeros(n_max)

for idx, n in enumerate(n_values):
    t_n = n
    i_n = np.argmin(np.abs(t - t_n))
    u_n[idx] = u[i_n]

# 为 MG、MG2 和 MG3 任务准备输入和输出
delta_n = delta  # 因为 delta = 6

# 确保索引在有效范围内
n_samples = n_max - 3 * delta_n - delta_n  # 调整以考虑 u(n + 6)

# 初始化输入和输出数组
u_mg_input = np.zeros((n_samples, 4))
u_mg_output = np.zeros(n_samples)
u_mg1_input = np.zeros((n_samples, 3))
u_mg1_output = np.zeros(n_samples)
u_mg2_input = np.zeros((n_samples, 2))
u_mg2_output = np.zeros(n_samples)


for i in range(n_samples):
    idx = i + 3 * delta_n  # 确保索引有效
    # MG 任务
    u_mg_input[i, 0] = u_n[idx]  # u(n)
    u_mg_input[i, 1] = u_n[idx - delta_n]  # u(n - δ)
    u_mg_input[i, 2] = u_n[idx - 2 * delta_n]  # u(n - 2δ)
    u_mg_input[i, 3] = u_n[idx - 3 * delta_n]  # u(n - 3δ)
    u_mg_output[i] = u_n[idx + delta_n]  # y(n) = u(n + δ)

    # MG1 任务
    u_mg1_input[i, 0] = u_n[idx - delta_n]     # u(n - δ)
    u_mg1_input[i, 1] = u_n[idx - 2 * delta_n] # u(n - 2δ)
    u_mg1_input[i, 2] = u_n[idx - 3 * delta_n] # u(n - 3δ)
    u_mg1_output[i] = u_n[idx + delta_n]       # y(n) = u(n + δ)

    # MG2 任务
    u_mg2_input[i, 0] = u_n[idx - 2 * delta_n] # u(n - 2δ)
    u_mg2_input[i, 1] = u_n[idx - 3 * delta_n] # u(n - 3δ)
    u_mg2_output[i] = u_n[idx + delta_n]       # y(n) = u(n + δ)



# 将数据保存为 CSV 文件

# MG 任务数据
mg_data = np.hstack((u_mg_input, u_mg_output.reshape(-1, 1)))
mg_columns = ['u_n', 'u_n_minus_delta', 'u_n_minus_2delta', 'u_n_minus_3delta', 'y_n_plus_delta']
mg_df = pd.DataFrame(mg_data, columns=mg_columns)
mg_df.to_csv('MG_data.csv', index=False)

# MG1 任务数据
mg1_data = np.hstack((u_mg1_input, u_mg1_output.reshape(-1,1)))
mg1_columns = ['u_n_minus_delta', 'u_n_minus_2delta', 'u_n_minus_3delta', 'y_n_plus_delta']
mg1_df = pd.DataFrame(mg1_data, columns=mg1_columns)
mg1_df.to_csv('MG1_data.csv', index=False)

# MG2 任务数据
mg2_data = np.hstack((u_mg2_input, u_mg2_output.reshape(-1,1)))
mg2_columns = ['u_n_minus_2delta', 'u_n_minus_3delta', 'y_n_plus_delta']
mg2_df = pd.DataFrame(mg2_data, columns=mg2_columns)
mg2_df.to_csv('MG2_data.csv', index=False)


plt.figure(figsize=(16, 4))
plt.plot(range(N)[300:], u[300:], 'r-', label='Test Target')

plt.xlabel('X')
plt.ylabel('Y')
# 设置 y 轴范围
# plt.ylim(0.4, 1.5)  # y 轴的范围设定为 -2 到 2
plt.legend()
plt.show()

print("数据已成功保存为 CSV 文件：MG_data.csv、MG1_data.csv、MG2_data.csv")
